﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using IQReportes.Models;
using IQReportes.Utils;

namespace IQReportes.Boundary
{
    public class FormatterTransacciones
    {
        
        //public static List<string[]> consolidadoToChartView(List<ConsolidadoGeneral> consolidado, int tipoChart)
        //{
        //    List<string[]> retorno;
        //    retorno = (from item in consolidado
        //                              select (item.obtenerArreglo())
        //                                  ).ToList();
        //    retorno.Insert(0, consolidado[0].obtenerCabecera(1));
        //    retorno.Insert(0, consolidado[0].obtenerCabecera(2));
                        
        //    //para columna 
        //    //para cons tipos, y estados.
        //    List<string> auxFila1 = new List<string>();
        //    List<string> auxFila2 = new List<string>();
        //    for(int i= 0; i<consolidado.Count();i++)
        //    {
        //        auxFila1.Add("number");
        //        auxFila2.Add(consolidado[i].obtenerCantidad());
        //    }
        //    retorno.Add(auxFila1.ToArray());

        //    return retorno;
        //}

        public static List<string[]> consEstadoToChartView(List<ConsolidadoEstadoTransaccion> consolidado,
                                                            int tipoChart, int numDias)
        {
            //para Columna todos los consolidados
            List<string[]> retorno = new List<string[]>();

            if (tipoChart == Constantes.COLUMNCHART)
            {
                List<string> auxFila1 = new List<string>();
                List<string> auxFila2 = new List<string>();
                List<string> auxFila3 = new List<string>();
                var consColumna = consolidado.AsQueryable().GroupBy(a => a.vcEstado).Select(k =>
                    new { estado = k.Key, cantidad = k.Sum(x => x.inCantidad) }).ToList();

                auxFila1.Add("string");
                auxFila2.Add("Estado");
                auxFila3.Add("Cantidad");
                foreach (var e in consColumna)
                {
                    auxFila1.Add("number");
                    auxFila2.Add(e.estado);
                    auxFila3.Add(e.cantidad.ToString());
                }

                retorno.Add(auxFila1.ToArray());
                retorno.Add(auxFila2.ToArray());
                retorno.Add(auxFila3.ToArray());
                return retorno;
            }
            else if(tipoChart == Constantes.PIECHART || tipoChart == Constantes.TABLECHART)
            {
                //para pie ya stá
                retorno = (from item in consolidado
                           select (item.obtenerArreglo())
                                          ).ToList();
                retorno.Insert(0, consolidado[0].obtenerCabecera(1));
                retorno.Insert(0, consolidado[0].obtenerCabecera(2));
                return retorno;
            }

            else if(tipoChart == Constantes.LINECHART)
            {
                List<List<string>> listaGeneral = new List<List<string>>();
                List<string> elementoLista,cabecera,tiposDato;
                int cantidadFechas=1;            
                //creo tantas listas como fechas tenga en el consolidado
                elementoLista = new List<string>();
                
                var estados = consolidado.AsQueryable().GroupBy(a => new { a.vcEstado }).Select(k => 
                    new {estado = k.Key.vcEstado }).ToList();
                cabecera = new List<string>();
                tiposDato = new List<string>();

                tiposDato.Add("string");
                cabecera.Add("Fecha");
                foreach (var e in estados)
                {
                    tiposDato.Add("number");
                    cabecera.Add(e.estado);
                }

                var consColumna1 = consolidado.AsQueryable().GroupBy(a => new { a.vcSemana }).Select(k =>
                                                                new { fecha = k.Key.vcSemana }).ToList();

                retorno.Add(tiposDato.ToArray());
                retorno.Add(cabecera.ToArray());
                if (numDias <= Constantes.DIA)
                {
                    var consColumna = consolidado.AsQueryable().GroupBy(a => new { a.dtFecha }).Select(k =>
                    new { fecha = k.Key.dtFecha }).ToList();
                    cantidadFechas = consColumna.Count();
                    //para cada una de las fechas se ingresa una lista de strings cn las cantidades de c/estado
                    for (int i = 0; i < cantidadFechas; i++)
                    {
                        elementoLista = new List<string>();
                        //se agrega la fecha correspondiente a la primera columna
                        elementoLista.Add(consColumna[i].fecha.ToString("dd/MM/yyyy")); 
                        var consAux = consolidado.Where(a => a.dtFecha == consColumna[i].fecha).ToList();
                        //puede que para una fecha se hayan realizado ciertos estados de txns que no se encuentran
                        //en otra fecha y viceversa
                        foreach (var e in estados)
                        {
                            var elementoEstado = consAux.AsQueryable().Where(a => a.vcEstado == e.estado);
                            if (elementoEstado.Count() > 0)
                            {
                                elementoLista.Add(elementoEstado.First().inCantidad.ToString());
                            }
                            else
                            {
                                elementoLista.Add("0");
                            }
                        }
                        retorno.Add(elementoLista.ToArray());
                    }
                    return retorno;

                }
                else if (numDias <= Constantes.SEMANA)
                {
                    cantidadFechas = consColumna1.Count();
                }
                else if (numDias <= Constantes.MES)
                {
                    consColumna1 = consolidado.AsQueryable().GroupBy(a => new { a.vcMes }).Select(k =>
                                                                new { fecha = k.Key.vcMes }).ToList(); 
                    cantidadFechas = consColumna1.Count();
                }
                else
                {
                    var consColumna = consolidado.AsQueryable().GroupBy(a => new { a.inAno }).Select(k =>
                                                                new { fecha = k.Key.inAno }).ToList();
                    cantidadFechas = consColumna.Count();

                    //para cada una de las fechas se ingresa una lista de strings cn las cantidades de c/estado
                    for (int i = 0; i < cantidadFechas; i++)
                    {
                        elementoLista = new List<string>();
                        //se agrega la fecha correspondiente a la primera columna
                        elementoLista.Add(consColumna[i].fecha.ToString());
                        var consAux = consolidado.Where(a => a.inAno == consColumna[i].fecha).ToList();

                        foreach (var e in estados)
                        {
                            var elementoEstado = consAux.AsQueryable().Where(a => a.vcEstado == e.estado);
                            if (elementoEstado.Count() > 0)
                            {
                                elementoLista.Add(elementoEstado.First().inCantidad.ToString());
                            }
                            else
                            {
                                elementoLista.Add("0");
                            }
                        }
                        retorno.Add(elementoLista.ToArray());
                    }
                    return retorno;

                }

                for (int i = 0; i < cantidadFechas; i++)
                {
                    elementoLista = new List<string>();
                    //se agrega la fecha correspondiente a la primera columna
                    elementoLista.Add(consColumna1[i].fecha);
                    //se busca el consolidado con respecto a la fecha respectiva
                    var consAux = consolidado.Where(a => a.vcSemana == consColumna1[i].fecha).ToList();
                    foreach (var e in estados)
                    {
                        var elementoEstado = consAux.AsQueryable().Where(a => a.vcEstado == e.estado);
                        if (elementoEstado.Count() > 0)
                        {
                            elementoLista.Add(elementoEstado.First().inCantidad.ToString());
                        }
                        else
                        {
                            elementoLista.Add("0");
                        }
                    }
                    retorno.Add(elementoLista.ToArray());
                }

                return retorno;
            }
            return null;
        }


        public static List<string[]> consMontoToChartView(List<ConsolidadoMontoTransaccion> consolidado, int tipoChart,
                                                            int nivel, int numDias)
        {
            List<string[]> retorno = new List<string[]>();
            double abono = 0; double cargo = 0; double transf = 0; double monto = 0;
            
            for (int i = 0; i < consolidado.Count(); i++)
            {
                abono += consolidado[i].dbAbono;
                cargo += consolidado[i].dbCargo;
                transf += consolidado[i].dbTransferencia;
                monto += consolidado[i].dbMonto;
            }
            
            if (tipoChart == Constantes.COLUMNCHART)
            {
                List<string> auxFila = new List<string>();
                
                //auxFila.Add("Periodo"); //aca va una fecha CONSOLIDADA
                auxFila.Add("Cantidad");
                auxFila.Add(abono.ToString());
                auxFila.Add(cargo.ToString());
                auxFila.Add(transf.ToString());
                //auxFila.Add(monto.ToString());

                List<String> cabecera = new List<String>();
                cabecera.Add("Cantidad"); cabecera.Add("Abono"); cabecera.Add("Cargo"); cabecera.Add("Transferencias");
                retorno.Insert(0, cabecera.ToArray());

                cabecera = new List<String>();
                cabecera.Add("string"); cabecera.Add("number"); cabecera.Add("number"); cabecera.Add("number");
                retorno.Insert(0, cabecera.ToArray());

                retorno.Add(auxFila.ToArray());
                
                return retorno;
            }
            else if (tipoChart == Constantes.PIECHART)
            {
            
                List<string> cabecera = new List<string>();
                
                cabecera.Add("string"); cabecera.Add("number");
                retorno.Add(cabecera.ToArray());

                cabecera = new List<string>();
                cabecera.Add("Tipo de Movimiento"); cabecera.Add("Valor");
                retorno.Add(cabecera.ToArray());

                agregarElementoPieMonto("Abono",abono.ToString(),retorno);
                agregarElementoPieMonto("Cargo",cargo.ToString(),retorno);
                agregarElementoPieMonto("Transferencia", transf.ToString(), retorno);
                
                //agregarElementoPieMonto("Monto", transf.ToString(), retorno);

                return retorno;
                
            }
            else if (tipoChart == Constantes.TABLECHART)
            {
                retorno = (from item in consolidado
                           select (item.obtenerArreglo(tipoChart, nivel))
                                              ).ToList();
                retorno.Insert(0, consolidado[0].obtenerCabecera(1, nivel));
                retorno.Insert(0, consolidado[0].obtenerCabecera(2, nivel));

                return retorno;
            }
            else
            {
                retorno = (from item in consolidado
                           select (item.obtenerArreglo(tipoChart, nivel))
                                              ).ToList();

                List<String> cabecera = new List<String>();
                cabecera.Add("Fecha"); cabecera.Add("Abono"); cabecera.Add("Cargo"); cabecera.Add("Transferencias");
                retorno.Insert(0, cabecera.ToArray());

                cabecera = new List<String>();
                cabecera.Add("string"); cabecera.Add("number"); cabecera.Add("number"); cabecera.Add("number");
                retorno.Insert(0, cabecera.ToArray());

                return retorno;
            }
            
        }

        private static void agregarElementoPieMonto(string col1, string col2, List<string[]> retorno)
        {
            List<string> elemento = new List<string>();
            elemento.Add(col1);
            elemento.Add(col2);
            retorno.Add(elemento.ToArray());
        }


        public static List<string[]> consTipoToChartView(List<ConsolidadoTipoTransaccion> consolidado,int tipoChart, int numDias,
                                                            int? idEstadoTx)
        {
            //FALTA
            List<string[]> retorno = new List<string[]>();

            if (tipoChart == Constantes.COLUMNCHART)
            {
                List<string> auxFila1 = new List<string>();
                List<string> auxFila2 = new List<string>();
                List<string> auxFila3 = new List<string>();
                var consColumna = consolidado.AsQueryable().GroupBy(a => a.vcNombreTipoTransaccion).Select(k =>
                    new { tipoTxn = k.Key, cantidad = k.Sum(x => x.inCantidad) }).ToList();

                auxFila1.Add("string");
                auxFila2.Add("Fecha");
                auxFila3.Add("Cantidad");
                foreach (var e in consColumna)
                {
                    auxFila1.Add("number");
                    auxFila2.Add(e.tipoTxn);
                    auxFila3.Add(e.cantidad.ToString());
                }

                retorno.Add(auxFila1.ToArray());
                retorno.Add(auxFila2.ToArray());
                retorno.Add(auxFila3.ToArray());
                return retorno;
            }
            else if (tipoChart == Constantes.PIECHART)
            {
                //para pie ya stá
                retorno = (from item in consolidado
                           select (item.obtenerArreglo(tipoChart,idEstadoTx))
                                          ).ToList();
                retorno.Insert(0, consolidado[0].obtenerCabecera(1,tipoChart, idEstadoTx));
                retorno.Insert(0, consolidado[0].obtenerCabecera(2,tipoChart, idEstadoTx));
                return retorno;
            }

            else if (tipoChart == Constantes.LINECHART)
            {
                List<List<string>> listaGeneral = new List<List<string>>();
                List<string> elementoLista, cabecera, tiposDato;
                int cantidadFechas = 1;
                //creo tantas listas como fechas tenga en el consolidado
                elementoLista = new List<string>();

                var tiposTxn = consolidado.AsQueryable().GroupBy(a => new { a.vcNombreTipoTransaccion }).Select(
                    k => new { tipo = k.Key.vcNombreTipoTransaccion }).ToList();
                cabecera = new List<string>();
                tiposDato = new List<string>();

                tiposDato.Add("string");
                cabecera.Add("Fecha");
                foreach (var t in tiposTxn)
                {
                    tiposDato.Add("number");
                    cabecera.Add(t.tipo);
                }

                var consColumna1 = consolidado.AsQueryable().GroupBy(a => new { a.vcSemana }).Select(k =>
                                                                new { fecha = k.Key.vcSemana }).ToList();
                retorno.Add(tiposDato.ToArray());
                retorno.Add(cabecera.ToArray());
                if (numDias <= Constantes.DIA)
                {
                    var consColumna = consolidado.AsQueryable().GroupBy(a => new { a.dtFecha }).Select(k =>
                    new { fecha = k.Key.dtFecha }).ToList();
                    cantidadFechas = consColumna.Count();
                    //para cada una de las fechas se ingresa una lista de strings cn las cantidades de c/estado
                    for (int i = 0; i < cantidadFechas; i++)
                    {
                        elementoLista = new List<string>();
                        //se agrega la fecha correspondiente a la primera columna
                        elementoLista.Add(consColumna[i].fecha.ToString("dd/MM/yyyy"));
                        var consAux = consolidado.Where(a => a.dtFecha == consColumna[i].fecha).ToList();
                        //puede que para una fecha se hayan realizado cierto tipo de txns que no se encuentran
                        //en otra fecha y viceversa
                        foreach (var t in tiposTxn)
                        {
                            var elementoTipo = consAux.AsQueryable().Where(a => a.vcNombreTipoTransaccion == t.tipo);
                            if (elementoTipo.Count() > 0)
                            {
                                elementoLista.Add(elementoTipo.First().inCantidad.ToString());
                            }
                            else
                            {
                                elementoLista.Add("0");
                            }
                        }
                        retorno.Add(elementoLista.ToArray());
                    }
                    return retorno;

                }
                else if (numDias <= Constantes.SEMANA)
                {
                    cantidadFechas = consColumna1.Count();
                }
                else if (numDias <= Constantes.MES)
                {
                    consColumna1 = consolidado.AsQueryable().GroupBy(a => new { a.vcMes }).Select(k =>
                                                                new { fecha = k.Key.vcMes }).ToList();
                    cantidadFechas = consColumna1.Count();
                }
                else
                {
                    var consColumna = consolidado.AsQueryable().GroupBy(a => new { a.inAno }).Select(k =>
                                                                new { fecha = k.Key.inAno }).ToList();
                    cantidadFechas = consColumna.Count();
                    //para cada una de las fechas se ingresa una lista de strings cn las cantidades de c/estado
                    for (int i = 0; i < cantidadFechas; i++)
                    {
                        elementoLista = new List<string>();
                        //se agrega la fecha correspondiente a la primera columna
                        elementoLista.Add(consColumna[i].fecha.ToString());
                        var consAux = consolidado.Where(a => a.inAno == consColumna[i].fecha).ToList();

                        foreach (var t in tiposTxn)
                        {
                            var elementoEstado = consAux.AsQueryable().Where(a => a.vcNombreTipoTransaccion == t.tipo);
                            if (elementoEstado.Count() > 0)
                            {
                                elementoLista.Add(elementoEstado.First().inCantidad.ToString());
                            }
                            else
                            {
                                elementoLista.Add("0");
                            }
                        }
                        retorno.Add(elementoLista.ToArray());
                    }
                    return retorno;
                }

                for (int i = 0; i < cantidadFechas; i++)
                {
                    elementoLista = new List<string>();
                    //se agrega la fecha correspondiente a la primera columna
                    elementoLista.Add(consColumna1[i].fecha);
                    //se busca el consolidado con respecto a la fecha respectiva
                    var consAux = consolidado.Where(a => a.vcSemana == consColumna1[i].fecha).ToList();
                    foreach (var t in tiposTxn)
                    {
                        var elementoEstado = consAux.AsQueryable().Where(a => a.vcNombreTipoTransaccion == t.tipo);
                        if (elementoEstado.Count() > 0)
                        {
                            elementoLista.Add(elementoEstado.First().inCantidad.ToString());
                        }
                        else
                        {
                            elementoLista.Add("0");
                        }
                    }
                    retorno.Add(elementoLista.ToArray());

                }

                return retorno;
            }

            else
            {
                retorno = (from item in consolidado
                           select (item.obtenerArreglo(tipoChart,idEstadoTx))
                                          ).ToList();
                retorno.Insert(0, consolidado[0].obtenerCabecera(1, tipoChart, idEstadoTx));
                retorno.Insert(0, consolidado[0].obtenerCabecera(2, tipoChart, idEstadoTx));
                return retorno;
            }

        }
        public static List<string[]> consTreeToChartView(List<TreeTransaccion> consolidado, int tipoChart)
        {
            List<int> ff = new List<int>();
            foreach (var c in consolidado)
            {
                if (c.inColor > 0)
                {
                    ff.Add(c.inColor);
                }
            }
            List<string[]> retorno;
            retorno = (from item in consolidado
                       select (item.obtenerArreglo(Constantes.TREETRANSACCIONES))
                                          ).ToList();
            retorno.Insert(0, consolidado[0].obtenerCabecera(1));
            retorno.Insert(0, consolidado[0].obtenerCabecera(2));
            return retorno;
        }

        public static string stringToStringFecha(string fecha)
        {
            string fechaNueva = "";
            string[] estructuraFecha = fecha.Split('/');
            bool flag = true;
            foreach ( string cad in estructuraFecha){

                if (flag)
                    flag = false;
                else
                    fechaNueva += "/";

                if (cad.Length == 1)
                {
                    fechaNueva += "0";
                }
                fechaNueva += cad;
            }
            return fechaNueva;
        }
        

    }
}